package com.ccp.dev.workflow.service;

import com.ccp.dev.core.basic.base.BaseService;
import com.ccp.dev.core.basic.util.UUIDUtils;
import com.ccp.dev.core.basic.web.query.QueryFilter;
import com.ccp.dev.core.basic.util.ContextUtil;
import com.ccp.dev.core.basic.web.query.QueryFilter;
import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.system.model.SysRole;
import com.ccp.dev.system.model.SysUser;
import com.ccp.dev.system.service.SysUserService;
import com.ccp.dev.workflow.dao.FlowHandoverDao;
import com.ccp.dev.workflow.dao.TaskDao;
import com.ccp.dev.workflow.model.BpmTaskExe;
import com.ccp.dev.workflow.model.FlowHandover;
import com.ccp.dev.workflow.model.ProcessRun;
import com.ccp.dev.workflow.model.TaskOpinion;
import com.ccp.dev.workflow.model.bpm.BpmRunLog;
import com.ccp.dev.workflow.model.bpm.ProcessTask;
import com.ccp.dev.workflow.service.bpm.BpmRunLogService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
public class FlowHandoverService extends BaseService<FlowHandover> {
    @Resource
    private FlowHandoverDao flowHandoverDao;
    @Resource
    private BpmService bpmService;
    @Resource
    private TaskDao taskDao;
    @Resource
    private TaskService taskService;
    @Resource
    private AgentSettingService agentSettingService;
    @Resource
    private ProcessRunService processRunService;
    @Resource
    private BpmRunLogService bpmRunLogService;
    @Resource
    private TaskMessageService taskMessageService;
    @Resource
    private SysTemplateService sysTemplateService;
    @Resource
    private TaskOpinionService taskOpinionService;

    /**
     * 获取当前登录用户绑定的流程
     * @param queryFilter   查询条件
     * @return
     */
    public List<FlowHandover> queryFlowByUserId(QueryFilter queryFilter) {
        return flowHandoverDao.queryFlowByUserId(queryFilter);
    }

    /**
     * 获取当前登录用户角色绑定的流程
     * @param queryFilter   查询条件
     * @return
     */
    public List<FlowHandover> queryFlowByRoleIds(QueryFilter queryFilter) {
        return flowHandoverDao.queryFlowByRoleIds(queryFilter);
    }

    /**
     * 获取当前登录用户组织绑定的流程
     * @param queryFilter   查询条件
     * @return
     */
    public List<FlowHandover> queryFlowByOrgId(QueryFilter queryFilter) {
        return flowHandoverDao.queryFlowByOrgId(queryFilter);
    }


    /**
     * 返回只有我自己能审批的任务
     * @param queryFilter
     * @return List<ProcessTask>
     */
    public List<ProcessTask> queryAllTaskOnlyMe(QueryFilter queryFilter){
        String taskIds = queryAllTaskOfMe();
        if(StringUtil.isEmpty(taskIds)){
            return new ArrayList<ProcessTask>();
        }
        queryFilter.put("userId", ContextUtil.getCurrentUserId());
        queryFilter.put("taskIds",taskIds);
        return taskDao.queryTaskOnlyOfMe(queryFilter);
    }


    /**
     * 查询所有任务列表
     * @return list
     */
    public String queryAllTaskOfMe() {
        String userId = ContextUtil.getCurrentUserId();
        StringBuilder sb = new StringBuilder();
        //获取当前用户的所有任务
        List<String> taskIdList = taskDao.queryAllTaskOfMe(userId);
        for (String taskId:taskIdList) {
            if(taskDao.queryOtherApproverCountOfMyTask(taskId,userId)==0){
                sb.append("'"+taskId+"'"+",");
            }
        }
        if(sb.toString().length()>0){
            return sb.toString().substring(0,sb.toString().length()-1);
        }
        return "";
    }

    @Transactional(rollbackFor = Exception.class)
    public void handoverWork(String taskIds,SysUser receiver) throws Exception{
        String[] taskIdArray = taskIds.split(",");
        String currentUserId = ContextUtil.getCurrentUserId();
        SysUser currentUser = (SysUser)ContextUtil.getCurrentUser();
        TaskEntity task = null;
        SysUser agentUser = null;
        String newIdentityLinkId="";
        String receiverId = receiver.getUserId();
        Map<String,String> msgTempMap = sysTemplateService.getTempByFun(31);
        List<SysUser> receiverAgeUserList=new ArrayList<SysUser>();
        receiverAgeUserList.add(receiver);
        ProcessRun processRun = null;
        String allTaskOfMe = queryAllTaskOfMe();
        for (String taskId:taskIdArray) {
            if(allTaskOfMe.indexOf("'"+taskId+"'")<0){
                continue;
            }
            //获取任务
            task = bpmService.getTask(taskId);
            if (BeanUtils.isNotEmpty(task)) {
                processRun = processRunService.getByProcInstanceId(task.getProcessInstanceId());
                //确认是否只有我自己可以进行审批
                //查询任务接收人是否设置了代理，暂时先不做代理，因为任务转交代办的时候没有考虑代理，保持一直
                //agentUser = agentSettingService.getAgent(task,receiverId);
                /*String assignee = task.getAssignee();
                //当前用户是审批人
                if(assignee.equals(currentUserId)){
                    //修改任务的审批人为
                    taskService.setAssignee(taskId, agentUser==null?receiverId:agentUser.getUserId());
                }else{
                    //删除act_ru_identitylink表里的数据，角色、组织类型的不需要考虑
                    taskDao.delActRuIdentitylinkByTaskAndUser(taskId,currentUserId);
                    //在act_ru_identitylink里增加数据，只增加一条根据用户审批的数据即可满足要求
                    newIdentityLinkId = UUIDUtils.getUUIDFor32();
                    taskDao.insertIdentity(newIdentityLinkId,taskId,agentUser==null?receiverId:agentUser.getUserId());
                }*/
                //2020-03-09 jyq修改，将审批人直接改为交接人审批
                taskDao.updateTaskAssignee(taskId,receiverId);
                //记录审批意见
                addOpinion(processRun,task,receiver);
                //添加任务交接日志
                addHandoverLog(processRun,receiver.getFullName());
                //发送审批提醒消息
                taskMessageService.sendMessage(currentUser, receiverAgeUserList, "3", msgTempMap, processRun.getSubject(), "", taskId, null,null);
            }
        }

    }

    /**
     * 记录任务交接流程日志
     * @param processRun 流程运行对象
     * @param receiverName 被交接人的姓名
     */
    private void addHandoverLog(ProcessRun processRun,String receiverName){
        String memo = "任务交接："+"将任务交接给"+receiverName;
        bpmRunLogService.addRunLog(processRun,BpmRunLog.OPERATOR_TYPE_HANDOVER,memo);

    }

    private void addOpinion(ProcessRun processRun,TaskEntity task,SysUser receiver){

        SysUser curUser= (SysUser)ContextUtil.getCurrentUser();
        String description = task.getDescription();
        TaskOpinion taskOpinion = taskOpinionService.getByTaskId(task.getId());
        if(null==taskOpinion || TaskOpinion.STATUS_COMMUNICATION.toString().equals(description)||TaskOpinion.STATUS_TRANSTO.toString().equals(description)){
            //沟通任务或者流转任务
            //新增审批意见
            taskOpinion = new TaskOpinion();
            taskOpinion.setOpinionId(UUIDUtils.getUUIDFor32());
            taskOpinion.setOpinion("任务交接给"+receiver.getFullName());
            taskOpinion.setProcDefId(processRun.getProcDefId());
            taskOpinion.setProcInstId(processRun.getProcInstId());
            taskOpinion.setStartTime(new Date());
            taskOpinion.setEndTime(new Date());
            taskOpinion.setDurTime(0L);
            taskOpinion.setExeUserId(curUser.getUserId());
            taskOpinion.setExeFullname(curUser.getFullName());
            taskOpinion.setTaskKey(task.getTaskDefinitionKey());
            taskOpinion.setTaskName(task.getName());
            taskOpinion.setCheckStatus(TaskOpinion.STATUS_HANDOVER);
            taskOpinionService.add(taskOpinion);
        }else{
            // 将原来的任务审批意见修改成交办状态。
            taskOpinion.setCheckStatus(TaskOpinion.STATUS_HANDOVER);
            taskOpinion.setOpinion("任务交接给"+receiver.getFullName());
            taskOpinion.setEndTime(new Date());
            //时间间隔计算
            Long duration = taskOpinion.getEndTime().getTime() - taskOpinion.getStartTime().getTime();
            taskOpinion.setDurTime(duration);
            taskOpinion.setExeUserId(curUser.getUserId());
            taskOpinion.setExeFullname(curUser.getFullName());
            taskOpinionService.update(taskOpinion);


            //新添加一个任务意见，状态为初始值
            TaskOpinion newOpinion = new TaskOpinion();
            newOpinion.setOpinionId(UUIDUtils.getUUIDFor32());
            newOpinion.setProcInstId(processRun.getProcInstId());
            newOpinion.setProcDefId(processRun.getProcDefId());
            newOpinion.setCheckStatus(TaskOpinion.STATUS_CHECKING);
            newOpinion.setStartTime(new Date());
            newOpinion.setTaskKey(task.getTaskDefinitionKey());
            newOpinion.setTaskName(task.getName());
            newOpinion.setTaskId(task.getId());
            //加签会签时，获取流转的主任务
            while (task.getExecutionId()==null){
                String parentTaskId = task.getParentTaskId();
                task = bpmService.getTask(parentTaskId);
            }
            String superProcInstId = processRunService.getSuperProcInstId(task.getProcessInstanceId());
            newOpinion.setSuperExecution(superProcInstId);
            //外部子流程设置流程实例
            newOpinion.setProcInstId(task.getProcessInstanceId());
            newOpinion.setProcDefId(task.getProcessDefinitionId());
            taskOpinionService.add(newOpinion);
        }
    }

}
